package cn.brilliantfuture.commentry.plan.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.jboss.wsf.spi.annotation.WebContext;

import cn.brilliantfuture.commentry.entity.DeliveryPlan;
import cn.brilliantfuture.commentry.entity.OrderInformation;
import cn.brilliantfuture.commentry.plan.DeliveryPlanMessageRemote;
import cn.brilliantfuture.commentry.plan.DeliveryPlanMessageWebService;
import cn.brilliantfuture.commentry.util.BaseMessageImpl;
import cn.brilliantfuture.commentry.util.DateTimeHelper;
import cn.brilliantfuture.commentry.util.HttpUtil;
import cn.brilliantfuture.commentry.util.RESTUtil;

/**
 * 
 * Title: Communication Entry
 * 
 * Author: LiTian
 * 
 * Date: 2012-1-18
 * 
 * Description: 配送计划实现类
 * 
 */
@Stateless
@WebService(endpointInterface = "cn.brilliantfuture.commentry.plan.DeliveryPlanMessageWebService")
@WebContext(contextRoot = "/commentry", urlPattern = "/DeliveryPlanMessageWebService")
public class DeliveryPlanMessageImpl extends BaseMessageImpl implements DeliveryPlanMessageWebService, DeliveryPlanMessageRemote {

	protected static final Logger logger = Logger.getLogger(DeliveryPlanMessageImpl.class);

	protected static final String INVOKE_TIME_OUT = "invoke_time_out";
	protected static final String INVOKE_SUCCESS = "invoke_success";
	protected static final String INVOKE_FAILURE = "invoke_failure";
	protected static final String DEVICE_OFF_LINE = "device_off_line";
	protected static final String DEVICE_NOT_VAILD = "device_not_vaild";

	@PersistenceContext(unitName = "commentry-jpa")
	EntityManager entityManager;

	Calendar calendar = Calendar.getInstance();

	@SuppressWarnings("unchecked")
	public void invokePlan() {
		logger.info("DeliveryPlanMessageImpl.invokePlan()");

		calendar.setTime(new Date());

		calendar.add(Calendar.DATE, 1);
		String startTime = DateTimeHelper.dateTimeToStr(calendar.getTime(), DateTimeHelper.DEFAULT_DATE_FORMAT);

		calendar.add(Calendar.DATE, 1);
		String endTime = DateTimeHelper.dateTimeToStr(calendar.getTime(), DateTimeHelper.DEFAULT_DATE_FORMAT);

		String sql = "select dp from DeliveryPlan dp where dp.issue = 0 and dp.beginTime >= '" + startTime + " 00:00:00' and dp.endTime <= '" + endTime + " 00:00:00'";

		List<DeliveryPlan> list = entityManager.createQuery(sql).getResultList();
		StringBuffer deviceSn = new StringBuffer();
		StringBuffer storeMode = new StringBuffer();
		StringBuffer rfidSn = new StringBuffer();
		StringBuffer beginTime = new StringBuffer();
		StringBuffer finishTime = new StringBuffer();
		StringBuffer gridNum = new StringBuffer();
		StringBuffer deliveryPlanId = new StringBuffer();

		for (int i = 0; i < list.size(); i++) {
			deliveryPlanId.append(list.get(i).getDeliveryPlanId());
			deviceSn.append(list.get(i).getLockers().getDevice().getDeviceSn());
			storeMode.append(list.get(i).getOrderInformation().getStoreMode());
			rfidSn.append(list.get(i).getProductBatch().getRfidSn());
			gridNum.append(list.get(i).getStorageGrid().getGridNum());
			beginTime.append(DateTimeHelper.dateTimeToStr(list.get(i).getBeginTime(), "yyyyMMddHHmmss"));
			finishTime.append(DateTimeHelper.dateTimeToStr(list.get(i).getEndTime(), "yyyyMMddHHmmss"));

			if (i < list.size() - 1) {
				deliveryPlanId.append(",");
				deviceSn.append(",");
				storeMode.append(",");
				rfidSn.append(",");
				gridNum.append(",");
				beginTime.append(",");
				finishTime.append(",");
			}
		}

		if (list.size() > 0) {
			StringBuffer sb = new StringBuffer();
			sb.append(getRemoteUrl()).append("/deliveryplan/?").append("deviceSn=");
			sb.append(deviceSn).append("&gridNum=").append(gridNum);
			sb.append("&storeMode=").append(storeMode);
			sb.append("&rfidSn=").append(rfidSn);
			sb.append("&beginTime=").append(beginTime).append("&endTime=").append(finishTime);
			sb.append("&deliveryPlanId=").append(deliveryPlanId).append("&planType=").append(1);

			HttpUtil.getInvoke(sb.toString());
		}
	}

	public int revokePlan(String deviceSn, int deliveryPlanId, int planType, int gridNum, int storeMode, String rfidSn) {

		logger.info("DeliveryPlanMessageImpl.revokePlan(String deviceSn, int deliveryPlanId, int planType, int gridNum, int storeMode, String rfidSn)");

		StringBuffer sb = new StringBuffer();
		sb.append(getRemoteUrl()).append("/deliveryplan/?").append("deviceSn=");
		sb.append(deviceSn).append("&gridNum=").append(gridNum);
		sb.append("&storeMode=").append(storeMode);
		sb.append("&rfidSn=").append(rfidSn);
		sb.append("&deliveryPlanId=").append(deliveryPlanId).append("&planType=").append(planType);

		return Integer.parseInt(HttpUtil.getInvoke(sb.toString()));
	}

	@SuppressWarnings("unchecked")
	public void deliveryPlanCallback(Integer[] planTypes, Integer[] businessTypes, String[] storeCodes, Integer[] statuses) {
		logger.info("DeliveryPlanMessageImpl.callbackDeliveryPlan(Integer[] planTypes, Integer[] businessTypes, String[] storeCodes, Integer[] statuses)");

		StringBuffer sql = new StringBuffer();

		sql.append("select dp from DeliveryPlan dp where dp.productBatch.rfidSn in ('");

		for (int i = 0; i < storeCodes.length; i++) {
			sql.append(storeCodes[i]);

			if (i < storeCodes.length - 1)
				sql.append("', '");
		}

		sql.append("')");
		
		List<DeliveryPlan> deliveryPlans = entityManager.createQuery(sql.toString()).getResultList();
		
		JSONArray lockersIdArray = new JSONArray();
		JSONArray serviceTypeArray = new JSONArray();
		JSONArray storeCodeArray = new JSONArray();
		JSONArray reserveTypeArray = new JSONArray();
		JSONArray statusArray = new JSONArray();
		
		for (int i = 0; i < storeCodes.length; i++) {
			String storeCode = storeCodes[i];
			Integer planType = planTypes[i];
			Integer businessType = businessTypes[i];
			Integer status = statuses[i];
			
			for (DeliveryPlan deliveryPlan : deliveryPlans) {
				if (deliveryPlan.getProductBatch().getRfidSn().equals(storeCode) && deliveryPlan.getStorageGrid().getBusinessType() == businessType.intValue() && deliveryPlan.getPlanType() == planType.intValue()){
					
					if (deliveryPlan.getPlanType() == 2 && status > 0){
						deliveryPlan.setPlanType(1);
						deliveryPlan.setPublish(true);
					} else {
						deliveryPlan.setPublish(true);
					}
					
					if (deliveryPlan.getPlanType() == 2 && status == 0){
						OrderInformation orderInformation = deliveryPlan.getOrderInformation();
						orderInformation.setEffective(false);
						
						entityManager.merge(orderInformation);
					}

					entityManager.merge(deliveryPlan);
					
					if (deliveryPlan.getStorageGrid().getBusinessType() == 2){
						lockersIdArray.add(deliveryPlan.getLockers().getLockersId());
						serviceTypeArray.add(1);
						storeCodeArray.add(storeCode);
						reserveTypeArray.add(planType);
						statusArray.add(status);
					}
				}
			}
		}
		
		JSONObject field = new JSONObject();
		field.accumulate("lockers_ids", lockersIdArray);
		field.accumulate("service_types", serviceTypeArray);
		field.accumulate("store_codes", storeCodeArray);
		field.accumulate("reserve_types", reserveTypeArray);
		field.accumulate("statuses", statusArray);
		
		entityManager.flush();
		
		String result = RESTUtil.getRESTInvoke(RESTUtil.STORE_RESERVE_CALLBACK_METHOD, field.toString());
		
		logger.info("result -> " + result);
	}
}
